#include "stdio.h"
#include "stdlib.h"
#include "string.h"

/*
��һ�ࣺ��ʶ��   letter(letter | digit)*  ���
�ڶ��ࣺ����    (digit)+  ���
�����ࣺ������  (digit)+(.)?(digit)+(E|e)?(+|-)?(digit)+
�����ࣺ������(32)
auto       break    case     char        const      continue
default    do       double   else        enum       extern
float      for      goto     if          int        long
register   return   short    signed      sizeof     static
struct     switch   typedef  union       unsigned   void
volatile    while

�����ࣺ���  ��/*������//���� () { } [ ] " "  '
�����ࣺ����� <��<=��>��>=��=��+��-��*��/��^��>>��<<

�����п������Ž��б��룺
<$,0>
<auto,1>
...
<while,32>
<+��33>
<-,34>
<*,35>
</,36>
<<,37>
<<=,38>
<>,39>
<>=,40>
<=,41>
<==,42>
<!=,43>
<;,44>
<(,45>
<),46>
<^,47>
<,,48>
<",49>
<',50>
<#,51>
<&,52>
<&&,53>
<|,54>
<||,55>
<%,56>
<~,57>
<<<,58>����
<>>,59>����
<[,60>
<],61>
<{,62>
<},63>
<\,64>
<?,65>
<:,66>
<!,67>
<++,68>
<--,69>
<+=,70>
<-=,71>
<*=,72>
</=,73>
<%=,74>
"[","]","{","}"

<����96  ,��ֵ>
<������97 ,��ֵ>
<�ַ�98 , �ַ�>
<�ַ���99 ,�ַ���>
<��ʶ��100 ����ʶ��ָ��>
*/
char r[10000], token[20];
int pp = 0, cp = 0;
int syn = -1;
static char reserveWord[32][20] = {
    "auto", "break", "case", "char", "const", "continue",
    "default", "do", "double", "else", "enum", "extern",
    "float", "for", "goto", "if", "int", "long",
    "register", "return", "short", "signed", "sizeof", "static",
    "struct", "switch", "typedef", "union", "unsigned", "void",
    "volatile", "while"};
static char operatorOrDelimiter[36][10] = {
    "+", "-", "*", "/", "<", "<=", ">", ">=", "=", "==",
    "!=", ";", "(", ")", "^", ",", "\"", "\'", "#", "&",
    "&&", "|", "||", "%", "~", "<<", ">>", "[", "]", "{",
    "}", "\\", ".", "\?", ":", "!"};
int isReserveWord(char token[])
{
    for (int i = 0; i < 32; i++)
    {
        if (strcmp(token, reserveWord[i]) == 0)
            return i + 1;
    }
    return -1;
}
//ȥ��ע�ͣ��Ʊ���������ո�
void filterResource(char r[], int pProject)
{
    int count = 0;
    char temp[10000];
    for (int i = 0; i < pProject; i++)
    {
        //ȥ������
        if (r[i] == '\n')
        {
            while (r[++i] == ' ')
                ;
        }
        //ȥ��ע��
        if (r[i] == '/' && r[i + 1] == '/')
        {
            while (r[++i] != '\n')
                ;
            i--;
            continue;
        }
        if (r[i] == '/' && r[i + 1] == '*')
        {
            i++;
            while (r[++i] != '*')
            {
                if (r[i] == '$')
                {
                    printf("ע�ͳ��������������");
                    exit(0);
                }
            }
            i++;
            continue;
        }
        //ȥ���궨��
        if(r[i] == '#')
        {
           while (r[++i] != '\n')
                ;
            i--;
            continue;
        }
        if (r[i] != '\n' && r[i] != '\t' && r[i] != '\v' && r[i] != '\r')
            temp[count++] = r[i];
    }
    temp[--count] = '$';
    strcpy(r, temp);
}
int isDigit(char digit)
{
    return digit >= '0' && digit <= '9';
}
int isLetter(char letter)
{
    return letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <= 'Z' || letter == '_';
}
void next()
{
    while (r[cp] == ' ')
    {
        cp++;
    }
    char ch = r[cp];
    int count = 0;
    if (isLetter(ch))
    {
        do
        {
            token[count++] = r[cp++];
        } while (isLetter(r[cp]) || isDigit(r[cp]));
        token[count] = '\0';
        syn = isReserveWord(token);
        if (syn != -1)
            return;
        else
        {
            syn = 100;
        }
    }
    else if (ch == '\'')
    {
        token[count++] = r[++cp];
        token[count] = '\0';
        syn=98;
        cp+=2;
    }
    else if (ch == '"')
    {
        // printf("�����ַ���");
        cp++;
        while (r[cp] != '"')
        {
            token[count++] = r[cp++];
        }
        cp++;
        syn = 99;
    }
    else if (isDigit(ch))
    {
        do
        {
            token[count++] = r[cp++];
        } while (isDigit(r[cp]));
        if (r[cp] == '.')
        {
            do
            {
                token[count++] = r[cp++];
            } while (isDigit(r[cp]));
            if (r[cp] == 'E' || r[cp] == 'e')
            {
                token[count++] = r[cp++];
                if (r[cp] == '+' || r[cp] == '-')
                    token[count++] = r[cp++];
                do
                {
                    token[count++] = r[cp++];
                } while (isDigit(r[cp]));
            }
            syn = 97;
        }
        else if (r[cp] == 'E' || r[cp] == 'e')
        {
            token[count++] = r[cp++];
            if (r[cp] == '+' || r[cp] == '-')
                token[count++] = r[cp++];
            do
            {
                token[count++] = r[cp++];
            } while (isDigit(r[cp]));
            syn = 97;
        }
        else
        {
            syn = 96;
        }
    }
    else if (ch == '=')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 42;
        }
        else
        {
            syn = 41;
        }
    }
    else if (ch == '+')
    {
        token[count++] = r[cp++];
        if (r[cp] == '+')
        {
            token[count++] = r[cp++];
            syn = 68;
        }
        else if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 70;
        }
        else
        {
            syn = 33;
        }
    }
    else if (ch == '-')
    {
        token[count++] = r[cp++];
        if (r[cp] == '-')
        {
            token[count++] = r[cp++];
            syn = 69;
        }
        else if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 71;
        }
        else
        {
            syn = 34;
        }
    }
    else if (ch == '*')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 72;
        }
        else
        {
            syn = 35;
        }
    }
    else if (ch == '/')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 73;
        }
        else
        {
            syn = 36;
        }
    }
    else if (ch == '%')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 74;
        }
        else
        {
            syn = 56;
        }
    }
    else if (ch == '&')
    {
        token[count++] = r[cp++];
        if (r[cp] == '&')
        {
            token[count++] = r[cp++];
            syn = 52;
        }
        else
        {
           syn = 53;
        }  
    }
    else if (ch == '|')
    {
        token[count++] = r[cp++];
        if (r[cp] == '|')
        {
            token[count++] = r[cp++];
            syn = 55;
        }
        else
        {
           syn = 54;
        }  
    }
    else if (ch == '>')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 40;
        }
        else if (r[cp] == '>')
        {
            token[count++] = r[cp++];
            syn = 59;
        }
        else
        {
            syn = 39;
        }
    }
    else if (ch == '<')
    {
        token[count++] = r[cp++];
        if (r[cp] == '=')
        {
            token[count++] = r[cp++];
            syn = 38;
        }
        else if (r[cp] == '<')
        {
            token[count++] = r[cp++];
            syn = 58;
        }
        else
        {
            syn = 37;
        }
    }
    else if (ch == ';' || ch == '(' || ch == ')' || ch == '#' || ch == '[' || ch == ']' || ch == '{' || ch == '}' || ch == ',')
    {
        token[count++] = r[cp++];
        token[count] = '\0';
        for (int i = 0; i < 36; i++)
        {
            if (strcmp(token, operatorOrDelimiter[i]) == 0)
            {
                syn = 33 + i;
                break;
            }
        }
    }
    else if (r[cp] == '$')
    {
        syn = 0;
    }
    token[count] = '\0';
}
int main()
{
    // char resourceProject[10000];
    // int pProject = 0;
    FILE *fp;
    if ((fp = fopen("./test1.c", "r")) == NULL)
    {
        printf("can't open this file");
        exit(0);
    }
    r[pp] = fgetc(fp);
    while (r[pp] != EOF)
    {
        pp++;
        r[pp] = fgetc(fp);
    }
    r[++pp] = '\0';
    fclose(fp);
    printf("\n%s\n", "Դ����Ϊ:");
    printf(r);
    filterResource(r, pp);
    printf("\n%s\n", "���˺�ĳ���Ϊ:");
    printf("%s\n", r);
    while (syn != 0)
    {
        // printf("%c\n", r[cp]);
        next();
        printf("<%d,%s>\n", syn, token);
    }

    return 0;
}